package com.lightjet.macross.base.gateway;

import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixObservableCommand;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;

import java.util.List;

/**
 * @author : lijia
 * @version : 1.0 2019-10-21 14:43
 * description : 使用Spring Gateway的API网关启动类
 */
@SpringBootApplication(
        exclude = { HibernateJpaAutoConfiguration.class, DataSourceAutoConfiguration.class},
        scanBasePackages={"com.lightjet.macross.common","com.lightjet.macross.base.gateway"})
@Log
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.lightjet.macross.base.gateway.feign")
@EnableHystrix
public class BaseGatewayApplication {
    @Autowired
    private DiscoveryClient discoveryClient;

    public static void main(String[] args) {
        SpringApplication.run(BaseGatewayApplication.class, args);
    }

    //配置统一熔断
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        RouteLocatorBuilder.Builder result = builder.routes();
        //services列表
        List<String> services = discoveryClient.getServices();

        for (String service : services) {
            log.info("正在为服务【"+service+"】设置路由");
            result = result.route(p -> p
                    .path("/" + service + "/**")
                    .filters(f -> f
                            .stripPrefix(1) //映射路劲的时候把第一次个 /前的部分去掉
                            .hystrix(config -> config // 对path()指定的请求使用熔断器
                                    .setName("hystrix-" + service) // 熔断器的名字
                                    .setFallbackUri("forward:/fallback")// 熔断
                                    .setSetter(HystrixObservableCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(service))
                                            .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                                                    .withExecutionTimeoutInMilliseconds(5000))//超时
                                    )))
                    .uri("lb://" + service)); // 将请求路由到指定目标, lb开头是注册中心中的服务
        }

        return result.build();

    }
}
